package com.glq1218.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.glq1218.article.bo.AddArticleBO;
import com.glq1218.article.bo.ArticleBO;
import com.glq1218.article.bo.QueryArticleBO;
import com.glq1218.article.bo.UpdateArticleBO;
import com.glq1218.article.entity.Article;
import com.glq1218.article.mapper.ArticleMapper;
import com.glq1218.article.service.ArticleService;
import com.glq1218.category.mapper.CategoryMapper;
import com.glq1218.category.entity.Category;
import com.glq1218.domain.*;
import com.glq1218.user.mapper.UserMapper;
import com.glq1218.util.BeanCopyUtils;
import com.glq1218.util.SecurityUtils;
import com.glq1218.util.ServiceUtils;
import com.glq1218.util.SortUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.List;
import java.util.Objects;

/**
 * @author glq1218
 * @description TODO
 * @since 2023/4/23 9:47
 */
@Slf4j
@Service("articleService")
@RequiredArgsConstructor
@Transactional()
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
    private final CategoryMapper categoryMapper;
    private final UserMapper userMapper;

    @Override
    public PaginationResult<ArticleBO> queryArticleList(PaginationParam paginationParam, SortParam sortParam, IntervalStr intervalStr, QueryArticleBO queryArticleBO) {
        // 处理时间间隔
        Interval interval = ServiceUtils.getInterval(intervalStr);
        // 分页对象
        Page<Article> articlePage = ServiceUtils.getPage(paginationParam);
        // 构建查询条件对象
        String sortSql = "";
        if (StringUtils.hasText(sortParam.getSortField())) {
            sortSql = SortUtils.getSortSql(sortParam);
        }
        LambdaQueryWrapper<Article> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper
                .like(StringUtils.hasText(queryArticleBO.getName()), Article::getName, queryArticleBO.getName())
                .eq(Objects.nonNull(queryArticleBO.getStatus()), Article::getStatus, queryArticleBO.getStatus())
                .eq(Objects.nonNull(queryArticleBO.getCategoryId()), Article::getCategoryId, queryArticleBO.getCategoryId())
                .eq(Objects.nonNull(queryArticleBO.getUserId()), Article::getUserId, queryArticleBO.getUserId())
                .between(StringUtils.hasText(intervalStr.getUpdatedAtStart()) && StringUtils.hasText(intervalStr.getUpdatedAtEnd()),
                        Article::getUpdatedAt, interval.getUpdatedAtStart(), interval.getUpdatedAtEnd())
                .between(StringUtils.hasText(intervalStr.getCreatedAtStart()) && StringUtils.hasText(intervalStr.getCreatedAtEnd()), Article::getCreatedAt, interval.getCreatedAtStart(), interval.getCreatedAtEnd())
                // 默认就是使用主键id进行升序排序，可以配置其他字段，如修改日期等
                // .orderBy(!StringUtils.hasText(sortParam.getSortOrder()), true, Article::getId)
                .last(StringUtils.hasText(sortParam.getSortField()) && StringUtils.hasText(sortParam.getSortOrder()), sortSql);
        // 分页查询
        page(articlePage, lambdaQueryWrapper);
        // 获取总数，如果总数为0，就直接返回
        long total = articlePage.getTotal();
        if (total == 0L) {
            return PaginationResult.<ArticleBO>builder().total(0L).build();
        }
        // 将Article转为ArticleBO并设置角色信息
        IPage<ArticleBO> convert = articlePage.convert(this::getArticleBO);
        List<ArticleBO> articleBOList = convert.getRecords();
        return PaginationResult.<ArticleBO>builder().total(total).records(articleBOList)
                .build();
    }

    @Override
    public ArticleBO getArticleById(Serializable id) {
        Article article = getById(id);
        if (Objects.isNull(article)) {
            return null;
        }
        return getArticleBO(article);
    }

    /**
     * @param updateArticleBO 更新物品
     * @return 是否更新成功
     */
    @Override
    public String updateArticle(UpdateArticleBO updateArticleBO) {
        Article article = BeanCopyUtils.copyBean(updateArticleBO, Article.class);
        List<String> imgList = updateArticleBO.getImgList();
        boolean isSuccess;
        isSuccess = getBaseMapper().updateById(article) > 0;
        // 先删除该物品对应的所有图片信息
        if (Objects.nonNull(imgList)) {
            isSuccess = getBaseMapper().deleteArticleImg(article.getId()) > 0;
        }
        // 有角色信息的时候才进行添加用户角色信息的操作
        if (Objects.nonNull(imgList) && imgList.size() > 0) {
            // 再把新的用户角色对应信息插入到中间表中
            isSuccess = getBaseMapper().addArticleImg(article.getId(), imgList) > 0;
        }
        if (isSuccess) {
            log.info("用户信息更新成功{}", article);
            return "更新成功";
        }
        throw new RuntimeException("更新失败");
    }

    /**
     * @param addArticleBO 添加物品
     * @return 是否添加成功
     */
    @Override
    public String addArticle(AddArticleBO addArticleBO) {
        Article article = BeanCopyUtils.copyBean(addArticleBO, Article.class);
        // 设置发布人
        article.setUserId(SecurityUtils.getUserId());
        LambdaQueryWrapper<Article> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.orderByDesc(Article::getCreatedAt).last("limit 1");
        Long id = getBaseMapper().selectOne(lambdaQueryWrapper).getId();
        boolean isSuccess;
        isSuccess = getBaseMapper().insert(article) > 0;
        if (!CollectionUtils.isEmpty(addArticleBO.getImgList())) {
            isSuccess = getBaseMapper().addArticleImg(id + 1, addArticleBO.getImgList()) > 0;
        }
        if (isSuccess) {
            return "操作成功";
        }
        throw new RuntimeException("操作失败");
    }

    private ArticleBO getArticleBO(Article article) {
        ArticleBO articleBO = BeanCopyUtils.copyBean(article, ArticleBO.class);
        // 获取分类名称
        Category category = categoryMapper.getCategoryByArticleId(article.getCategoryId());
        articleBO.setCategoryName(category.getName());
        articleBO.setCategoryId(category.getId());
        // 获取物品图片
        List<String> imgList = getBaseMapper().queryImgListById(article.getId());
        articleBO.setImgList(imgList);
        // 获取发布人昵称
        String nickname = userMapper.getNicknameByUserId(article.getUserId());
        articleBO.setNickname(nickname);
        return articleBO;
    }
}
